import javax.media.j3d.*;
import javax.vecmath.*;
import com.sun.j3d.utils.geometry.*;
import com.sun.j3d.utils.universe.*;
import com.sun.j3d.utils.behaviors.vp.*;
import javax.swing.JFrame;


/**
* Eine einfache Demonstration des Picking-Behaviours. Es wird ausgegeben,
* welches der beiden dargestellten Objekt mit der Maus angeklickt wurde.
*
* @author Frank Klawonn
* Letzte Aenderung 07.07.2005
* @see PickingTest
*/
public class InteractionTest extends JFrame
{


  //Der Canvas, auf den gezeichnet wird.
  public Canvas3D myCanvas3D;



  public InteractionTest()
  {
    //Mechanismus zum Schliessen des Fensters und beenden des Programms
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);


    //Standardeinstellung fuer das Betrachteruniversum
    myCanvas3D = new Canvas3D(SimpleUniverse.getPreferredConfiguration());


    //Aufbau des SimpleUniverse:
    //Zuerst Erzeugen zusammen mit dem Canvas
    SimpleUniverse simpUniv = new SimpleUniverse(myCanvas3D);


    //Standardpositionierung des Betrachters
    simpUniv.getViewingPlatform().setNominalViewingTransform();


    //Die Szene wird in dieser Methode erzeugt.
    createSceneGraph(simpUniv);


    //Hinzufuegen von Licht
    addLight(simpUniv);


    //Hierdurch kann man mit der Maus den Betrachterstandpunkt veraendern
    OrbitBehavior ob = new OrbitBehavior(myCanvas3D);
    ob.setSchedulingBounds(new BoundingSphere(new Point3d(0.0,0.0,0.0),Double.MAX_VALUE));
    simpUniv.getViewingPlatform().setViewPlatformBehavior(ob);


    //Darstellung des Canvas/Fensters:
    setTitle("Welches Objekt wurde mit der Maus angeklickt?");
    setSize(700,700);
    getContentPane().add("Center", myCanvas3D);
    setVisible(true);

  }




  public static void main(String[] args)
  {
     InteractionTest interexam = new InteractionTest();
  }





  //In dieser Methode werden die Objekte der Szene aufgebaut und dem
  //SimpleUniverse su hinzugefuegt.
  public void createSceneGraph(SimpleUniverse su)
  {

//*** Erzeuge einen roten Wuerfel inklusive Transformationsgruppe ***
    Color3f ambientColourFBox = new Color3f(0.5f,0.0f,0.0f);
    Color3f emissiveColourFBox = new Color3f(0.0f,0.0f,0.0f);
    Color3f diffuseColourFBox = new Color3f(0.5f,0.0f,0.0f);
    Color3f specularColourFBox = new Color3f(0.8f,0.0f,0.0f);
    float shininessFBox = 10.0f;

    Appearance fBoxApp = new Appearance();

    fBoxApp.setMaterial(new Material(ambientColourFBox,emissiveColourFBox,
                          diffuseColourFBox,specularColourFBox,shininessFBox));


    Box fBox = new Box(0.2f,0.2f,0.2f,fBoxApp);

    //Die UserData werden benoetigt, um den Wuerfel beim Picking zu identifizieren.
    fBox.setUserData("Wuerfel");


    Transform3D tfFBox = new Transform3D();
    tfFBox.rotY(Math.PI/6);
    Transform3D rotationX = new Transform3D();
    rotationX.rotX(-Math.PI/5);
    tfFBox.mul(rotationX);
    TransformGroup tgFBox = new TransformGroup(tfFBox);

    tgFBox.addChild(fBox);



//*** Erzeuge eine gruene Kugel inklusive Transformationsgruppe ***
    Color3f ambientColourBSphere = new Color3f(0.0f,0.6f,0.0f);
    Color3f emissiveColourBSphere = new Color3f(0.0f,0.0f,0.0f);
    Color3f diffuseColourBSphere = new Color3f(0.0f,0.6f,0.0f);
    Color3f specularColourBSphere = new Color3f(0.0f,0.6f,0.0f);
    float shininessBSphere = 2.0f;

    Appearance bSphereApp = new Appearance();

    bSphereApp.setMaterial(new Material(ambientColourBSphere,emissiveColourBSphere,
                          diffuseColourBSphere,specularColourBSphere,shininessBSphere));

    Sphere bSphere = new Sphere(0.4f,bSphereApp);

    //Die UserData werden benoetigt, um die Kugel beim Picking zu identifizieren.
    bSphere.setUserData("Kugel");

    Transform3D tfBSphere = new Transform3D();
    tfBSphere.setTranslation(new Vector3f(2.0f,0.0f,-10.5f));
    TransformGroup tgBSphere = new TransformGroup(tfBSphere);
    tgBSphere.addChild(bSphere);

    //Erzeuge den Szenengraphen
    BranchGroup theScene = new BranchGroup();
    theScene.addChild(tgFBox);
    theScene.addChild(tgBSphere);

    //Definiere das PickingBehaviour, das verwendet werden soll, und fuege es zur Szene.
    BoundingSphere bs = new BoundingSphere(new Point3d(0.0,0.0,0.0),Double.MAX_VALUE);
    PickingTest sp = new PickingTest(myCanvas3D,theScene,bs);
    theScene.addChild(sp);

    theScene.compile();

    //Hinzufuegen der Szene
    su.addBranchGraph(theScene);

  }






  //Hier wird etwas Licht zu der Szene hinzugefuegt.
  public void addLight(SimpleUniverse su)
  {

    BranchGroup bgLight = new BranchGroup();

    BoundingSphere bounds = new BoundingSphere(new Point3d(0.0,0.0,0.0), Double.MAX_VALUE);

    //Direktionales Licht
    Color3f lightColour1 = new Color3f(1.0f,1.0f,1.0f);
    Vector3f lightDir1  = new Vector3f(-1.0f,0.0f,-0.5f);
    DirectionalLight light1 = new DirectionalLight(lightColour1, lightDir1);
    light1.setInfluencingBounds(bounds);

    bgLight.addChild(light1);


    //Streulicht
    Color3f lightColourAmb = new Color3f(0.5f, 0.5f, 0.5f);
    AmbientLight lightAmb = new AmbientLight(lightColourAmb);
    lightAmb.setInfluencingBounds(bounds);
    bgLight.addChild(lightAmb);


    su.addBranchGraph(bgLight);

  }


}
